﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
//字符和字符串函数

//strlrn函数统计\0之前出现的字符数(不包含\0)
//包含头文件 string.h
//返回类型size_t ,无符号整型
//两个无符号整型计算得到的是无符号整型
//strlen模拟实现
//size_t my_strlen(const char* str)
//{
//	size_t count = 0;
//	//要包含头文件assert.h
//	//assert()括号里面只要为假就会终止程序
//	//assert断言，当触发时通常会导致程序异常终止
//	//并打印一个错误消息，指示断言发生的文件和行号
//	assert(str);
//	while (*str)
//	{
//		count++;
//		str++;
//	}
//	return count;
//}
//int main() {
//	char arr[] = "abcdef";
//	size_t n = my_strlen(arr);
//	printf("%u\n", n);
//	return 0;
//}

//strcpy,字符串拷贝,拷⻉到源头字符串中的 \0 为⽌
//会将源字符串中的 '\0' 拷⻉到⽬标空间
//strcpy 函数返回的⽬标空间的起始地址
//⽬标空间必须⾜够⼤，以确保能存放源字符串。
//⽬标空间必须可修改
//char* strcpy(char* destination, const char* source)
//模拟实现
//char* my_strcpy(char* dest, const char* src)
//{
//	assert(dest && src);
//	char* ret = dest;
//	while (*src) {
//			*dest = *src;
//			dest++;
//			src++;
//	}
//	*(dest++) = '\0';
//	return ret;
//}
//int main()
//{
//	char arr1[10] = { 0 };
//	char arr2[] = "hello";
//	my_strcpy(arr1, arr2);
//	printf("%s\n", arr1);
//
//	return 0;
//}

//字符串追加，strcat
//char * strcat ( char * destination, const char * source 
//把source指向的源字符串中的所有字符都追加到destination指向的空间中
//strcat 函数返回的⽬标空间的起始地址
//源字符串必须以'\0'结束。
//⽬标字符串中也得有\0,否则没办法知道追加从哪⾥开始。
//⽬标空间必须有⾜够的⼤，能容纳下源字符串的内容。
//⽬标空间必须可修改
//模拟实现
//char* my_strcat(char* dest, const char* src)
//{
//	char* ret = dest;
//	assert(dest && src);
//	while (*dest)
//	{
//		dest++;
//	}
//	//先对dest和src解引用‌,将src指向的值赋给dest指向的位置。
//	//赋值完成后,dest 和src指针‌自增‌,指向下一个内存单元。
//	//赋值表达式的‌结果‌是*src的值（赋值前的值）
//	while ((*dest++ = *src++))
//	{
//		;
//	}
//	return ret;
//}
//int main()
//{
//	char arr1[20] = "hello ";
//	char arr2[] = "world";
//	my_strcat(arr1, arr2);
//	printf("%s\n", arr1);
//	return 0;
//}

//strcmp函数，比较两个字符串是否相等
//包含头文件string.h
//从两个字符串的第⼀个字符开始⽐较,如果两个字符的ASCII码值相等
//就⽐较下⼀个字符直到遇到不相等的两个字符,或者字符串结束
//第⼀个字符串>第⼆个字符串，则返回>0
//第⼀个字符串=第⼆个字符串，则返回0
//第⼀个字符串<第⼆个字符串，则返回<0
//模拟实现
//int my_strcmp(const char* str1, const char* str2)
//{
//	int ret = 0;
//	assert(str1 && str2);
//	
//	while (*str1 == *str2)
//	{
//		if (*str1 == '\0') {
//			return 0;//相等
//		}
//		str1++;
//		str2++;
//	}
//	return *str1 - *str2;
//}
//int main() {
//	char arr1[] = "abce";
//	char arr2[] = "abcd";
//	int ret = my_strcmp(arr1,arr2);
//	if (ret < 0) {
//		printf("<");
//	}
//	else if (ret == 0) {
//		printf("=");
//	}
//	else {
//		printf(">");
//	}
//	return 0;
//}

//strcpy,strcat,strcmp是长度不受限制的字符串函数

//长度受限制的字符串,相对安全
//strncpy,strncat,strncmp

//strncpy
//char* strncpy(char* destination,const char* source,size_t num )
//size_t num是拷贝的字符数
//int main()
//{
//	char arr1[20] = { 0 };
//	char arr2[] = "abcdefghi";
//	//当num>arr2中的字符数时，会在后面拿\0补充
//	char* str = strncpy(arr1, arr2, 5);
//	printf("%s\n", arr1);
//	printf("%s\n", str);
//
//	return 0;
//}

//strncat
//多个size_t num,表示追加的字符数
//int main()
//{
//	char arr1[20] = "hello ";
//	char arr2[] = "world";
//	//追加完字符之后会在整个字符串末尾补加一个\0
//	//函数中源字符串中不⼀定要有 \0 了
//  char* str = strncat(arr1, arr2, 4);
//	printf("%s\n", arr1);
//	printf("%s\n", str);
//
//	return 0;
//}

//strncmp
//size_t num,最多比较的字符串数
//int main()
//{
//	char arr1[] = "abcdef";
//	char arr2[] = "abcqw";
//
//	int ret1 = strncmp(arr1, arr2, 3);
//	printf("%d\n", ret1);
//	int ret2 = strncmp(arr1, arr2, 4);
//	printf("%d\n", ret2);
//
//	return 0;
//}


//strstr
//查找str2指向的子字符串在str1指向的字符串中第⼀次出现的位置。
//简⽽⾔之：在⼀个字符串中查找⼦字符串
//char* strstr(const char* str1,const char* str2)
//如果str1指向的字符串中存在str2指向的字符串，那么返回第⼀次出现位置的指针
//如果str1指向的字符串中不存在str2指向的字符串，那么返回NULL
//int main()
//{
//	char str[] = "This is a simple string";
//	char* pch;
//	pch = strstr(str, "simple");
//	if (pch != NULL)
//		printf("%s\n", pch);
//	else
//		printf("查找的字符串不存在\n");
//	return 0;
//}

//模拟实现
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	const char* s1 = str1;
	const char* s2 = str2;
	char* p = str1;
	//特殊情况：str2是空字符串时，直接返回str1 
	if (!*str2)
		return((char*)str1);
	while (*p)
	{
		s1 = p;
		s2 = str2;
		while (*s1 && *s2 && *s1 == *s2) {
			s1++;
			s2++;
		}
		if (*s2=='\0') {
			return(p); //返回第⼀次出现的起始 
		}
			p++;
	}
	return(NULL); //找不到则返回NULL 
}
int main() {
	char arr1[] = "i love u";
	char arr2[] = "love";
	char* ret = my_strstr(arr1,arr2);
	if (ret != NULL) {
		printf("%s\n", ret);
	}
	else {
		printf("未找到\n");
	}
	return 0;
}

